package gen

import (
	"gitee.com/whilew/gmodel/internal/util"
	"golang.org/x/tools/imports"
	"os"
	"path/filepath"
	"strings"
)

type (
	GenInput struct {
		Link             string `json:"link"`             // Database link.
		RemovePrefix     string `json:"removePrefix"`     // Remove table prefix.
		OutputDir        string `json:"outputDir"`        // 绝对输出目录
		TableTemplate    string `json:"tableTemplate"`    // Table template.
		FileNameTemplate string `json:"fileNameTemplate"` // Model file name template.

		//ClearAll     bool   `json:"clearAll"`     // Clear all model files.
	}
)

func GenEntity(input *GenInput, tables []*util.Table, f bool) error {
	if err := os.MkdirAll(input.OutputDir, os.ModePerm); err != nil {
		return err
	}
	generatedModel := GetGeneratedModel(input.OutputDir)
	var param = map[string]interface{}{}
	param["packageName"] = util.GetPackageName(input.OutputDir)
	for _, t := range tables {
		param["tableName"] = t.Name
		t.Desc = strings.ReplaceAll(t.Desc, "\n", "")
		t.Desc = strings.ReplaceAll(t.Desc, "\r", "")
		param["tableDesc"] = t.Desc
		fieldTypeMapping(t.Fields)
		param["fields"] = t.Fields

		fileName, err := util.GetTempText(input.FileNameTemplate, param)
		if err != nil {
			return err
		}
		if _, ok := generatedModel[fileName]; !f && ok {
			continue
		}
		content, err := util.GetTempText(input.TableTemplate, param)
		if err != nil {
			return err
		}
		data, err := imports.Process(filepath.Join(input.OutputDir, fileName), []byte(content), nil)
		if err != nil {
			return err
		}
		f, err := os.Create(filepath.Join(input.OutputDir, fileName))
		if err != nil {
			return err
		}
		defer f.Close()
		f.Write(data)
	}
	// TODO
	return nil
}

func fieldTypeMapping(field []*util.Field) {
	for _, t := range field {
		switch t.Type {
		case "int", "tinyint", "smallint", "mediumint", "bigint":
			t.Type = "int"
		case "float", "double", "decimal":
			t.Type = "float64"
		case "char", "varchar", "text", "longtext", "mediumtext", "tinytext":
			t.Type = "string"
		case "date", "datetime", "timestamp":
			t.Type = "time.Time"
		case "json":
			t.Type = "string"
		case "bool":
			t.Type = "bool"
		case "uint64", "*time.Time":
			t.Type = t.Type
		default:
			t.Type = "interface{}"
		}
	}
}
